import {
    api,
} from '@/lib/api';
import {
    TABBAR_PAGES,
} from '@/lib/constant';
import { createDecorator } from 'vue-class-component';

export const url = process.env.VUE_API_URL;
export const placeholderImg = 'https://img.yzcdn.cn/vant/cat.jpeg';

const chWeekDay = ['日', '一', '二', '三', '四', '五', '六', '日'];

const monthDay = [
    0,
    31,
    28,
    31,
    30,
    31,
    30,
    31,
    31,
    30,
    31,
    30,
    31,
];

/**
 * 是否是null或者undefined
 *
 * @param {} v 参数
 *
 * @return {boolean}
 */
export function isUndef(v) {
    return v === null || v === undefined;
}

/**
 * 等待毫秒数
 */
export function wait(ms) {
    return new Promise<void>((resolve) => {
        setTimeout(() => {
            resolve();
        }, ms);
    });
}

/**
 * 是否是某种类型
 */
export function isType(name) {
    return val => Object.prototype.toString.call(val) === `[object ${name}]`;
}

export const isArray = Array.isArray || isType('Array');
export const isString = isType('String');
export const isFunction = isType('Function');
export const isPlainObject = isType('Object');

/*
 * 日期文本解析
 *
 * @param {String} v 要求必须是 1. Y-m-d H:i:s 2. Y-m-d
 *
 * @return {Date} 解析后的日期
 */
export function dateParse(v) {
    if (isUndef(v) || v === '') {
        return v;
    }
    const chunk = v.split(' ');
    const date = chunk[0];
    const time = chunk[1];
    const dateChunk = date.split('-');
    const d = new Date();
    d.setFullYear(dateChunk[0]);
    d.setMonth(dateChunk[1] - 1);
    d.setMonth(dateChunk[1] - 1);
    d.setDate(dateChunk[2]);
    let hour = 0;
    let minute = 0;
    let second = 0;
    if (!isUndef(time)) {
        const timeChunk = time.split(':');
        hour = timeChunk[0];
        minute = timeChunk[1];
        second = timeChunk[2];
    }
    d.setHours(hour);
    d.setMinutes(minute);
    d.setSeconds(second);
    d.setMilliseconds(0);
    return d;
}

/**
 * 对于数字进行format操作
 */
export function tenFormat(number) {
    if (number < 0) {
        return number;
    } else if (number < 10) {
        return `0${number}`;
    } else {
        return number;
    }
}

/**
 * 获得当天的Date，要求北京时区
 *
 * @return {Date} 当天日期
 */
export function dateToday() {
    const date = new Date();
    return dateParse(`${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} 00:00:00`);
}

/**
 * 日期格式化
 *
 * @param {Date|Number} v
 * @param {String} format 格式内容
 *
 * @return {string} 经过format的日期数据
 */
export function dateFormat(v: any, format?: string): string {
    const type = typeof v;
    if (isUndef(v) || (type !== 'number' && !(v instanceof Date)) || v === '') {
        return v;
    }
    // 使用默认的format
    if (!format) {
        format = 'Y-M-D';
    }
    if (typeof v === 'number') {
        v = new Date(v);
    }

    format = format.replace('Y', v.getFullYear());
    format = format.replace('m', v.getMonth() + 1);
    format = format.replace('M', tenFormat(v.getMonth() + 1));
    format = format.replace('d', v.getDate());
    format = format.replace('D', tenFormat(v.getDate()));
    format = format.replace('H', tenFormat(v.getHours()));
    format = format.replace('i', tenFormat(v.getMinutes()));
    format = format.replace('s', tenFormat(v.getSeconds()));

    return format;
}

/**
 * 日期格式化
 *
 * @param {Date|Number} v
 * @param {String} format 格式内容
 *
 * @return {string} 经过format的日期数据
 */
export function dateChinaFormat(v, format) {
    const type = typeof v;
    if (isUndef(v) || (type !== 'number' && !(v instanceof Date))) {
        return v;
    }
    // 使用默认的format
    if (!format) {
        format = 'Y-m-d';
    }
    if (typeof v === 'number') {
        v = new Date(v);
    } else {
        v = new Date(v.valueOf());
    }

    format = format.replace('Y', String(v.getFullYear()));
    format = format.replace('m', String(tenFormat(v.getMonth() + 1)));
    format = format.replace('d', String(tenFormat(v.getDate())));
    format = format.replace('H', String(tenFormat(v.getHours())));
    format = format.replace('i', String(tenFormat(v.getMinutes())));
    format = format.replace('s', String(tenFormat(v.getSeconds())));

    return format;
}

/**
 * 移动日期
 *
 * @param {Date} v 传入进来的日期
 * @param {} count
 */
export function dateOffset(val, count, unit = 'day') {
    if (isUndef(val)) {
        return val;
    }
    if (unit === 'day') {
        return new Date(new Date(val).valueOf() + (count * 86400000));
    } else if (unit === 'month') {
        let time = val.valueOf();
        let date = new Date(time);
        for (let i = 0; i < count; i++) {
            time += getMonthDay(getYear(date), getMonth(date) + 1) * 86400000;
            date = new Date(time);
        }
        return date;
    }
}

/**
 * 获得当前的时间
 *
 * @return {Date} 当天
 */
export function dateNow() {
    const date = new Date();
    return dateParse(`${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`);
}

export function getYear(date) {
    return date.getFullYear();
}

export function getMonth(date) {
    return date.getMonth();
}

/**
 * 是否是闰年
 */
export function isLeapYear(year) {
    if (year % 4 !== 0) {
        return false;
    }
    if (year % 400 === 0) {
        return true;
    }
    if (year % 100 === 0) {
        return false;
    }
    return true;
}

/**
 * 获得一个月有多少天
 *
 * @param {} year 年份
 * @param {} month 月份 如果是1月就写1
 */
export function getMonthDay(year, month) {
    if (isLeapYear(year) && month === 2) {
        return 29;
    }
    return monthDay[month];
}

/**
 * 金额格式化，当存在小数时，将显示两位小数
 *
 * @param {} v 金额数据
 *
 * @return {string}
 */
export function currency(v, fixed = 2, divider = 100) {
    if (isUndef(v)) {
        return v;
    }

    const result = String((v / (divider || 100)).toFixed(fixed || 2));
    const pos = result.indexOf('.00');
    if (pos !== -1) {
        return result.substr(0, pos);
    } else {
        return result;
    }
}

/**
 * 金额格式化，当存在小数时，将显示两位小数
 *
 * @param {} v 金额数据
 *
 * @return {string}
 */
export function currencyPreserve(v, fixed = 2, divider = 100) {
    if (isUndef(v)) {
        return v;
    }

    return String((v / (divider || 100)).toFixed(fixed || 2));
}

/**
 * 日期天数差距
 *
 * @param {} v 较小的日期
 * @param {} c 比较的日期
 *
 * @return {number} 差距天数，当差距小于1天的时候，将不进行处理
 */
export function dateDiff(v, c, mode = 'floor') {
    if (isUndef(v)) {
        return v;
    }
    if (mode === 'floor') {
        return Math.floor((c.valueOf() - v.valueOf()) / 86400000);
    } else {
        return Math.ceil((c.valueOf() - v.valueOf()) / 86400000);
    }
}

/**
 * 返回weekDay的中文
 *
 * @param {Date} v
 */
export function toChWeekDay(v, format) {
    if (isUndef(v)) {
        return v;
    }
    v = v.getDay();
    if (isUndef(chWeekDay[v])) {
        return v;
    }
    if (!isUndef(format)) {
        return format.replace(/d/g, chWeekDay[v]);
    } else {
        return chWeekDay[v];
    }
}

/**
 * 生成map
 * @param {} arr
 * @param {} key
 */
export function makeMap(arr, key, setter) {
    const map = {};
    for (let i = 0, len = arr.length; i < len; i++) {
        map[arr[i][key]] = setter ? setter(arr[i]) : arr[i];
    }
    return map;
}

/**
 * 处理富文本里的图片宽度自适应
 * 1.去掉img标签里的style、width、height属性
 * 2.img标签添加style属性：max-width:100%;height:auto
 * 3.修改所有style里的width属性为max-width:100%
 * 4.去掉<br/>标签
 * @param html
 * @returns {void|string|*}
 */
// HTML 支持的数学符号
function strNumDiscode(str) {
    str = str.replace(/&forall;/g, '∀');
    str = str.replace(/&part;/g, '∂');
    str = str.replace(/&exist;/g, '∃');
    str = str.replace(/&empty;/g, '∅');
    str = str.replace(/&nabla;/g, '∇');
    str = str.replace(/&isin;/g, '∈');
    str = str.replace(/&notin;/g, '∉');
    str = str.replace(/&ni;/g, '∋');
    str = str.replace(/&prod;/g, '∏');
    str = str.replace(/&sum;/g, '∑');
    str = str.replace(/&minus;/g, '−');
    str = str.replace(/&lowast;/g, '∗');
    str = str.replace(/&radic;/g, '√');
    str = str.replace(/&prop;/g, '∝');
    str = str.replace(/&infin;/g, '∞');
    str = str.replace(/&ang;/g, '∠');
    str = str.replace(/&and;/g, '∧');
    str = str.replace(/&or;/g, '∨');
    str = str.replace(/&cap;/g, '∩');
    str = str.replace(/&cup;/g, '∪');
    str = str.replace(/&int;/g, '∫');
    str = str.replace(/&there4;/g, '∴');
    str = str.replace(/&sim;/g, '∼');
    str = str.replace(/&cong;/g, '≅');
    str = str.replace(/&asymp;/g, '≈');
    str = str.replace(/&ne;/g, '≠');
    str = str.replace(/&le;/g, '≤');
    str = str.replace(/&ge;/g, '≥');
    str = str.replace(/&sub;/g, '⊂');
    str = str.replace(/&sup;/g, '⊃');
    str = str.replace(/&nsub;/g, '⊄');
    str = str.replace(/&sube;/g, '⊆');
    str = str.replace(/&supe;/g, '⊇');
    str = str.replace(/&oplus;/g, '⊕');
    str = str.replace(/&otimes;/g, '⊗');
    str = str.replace(/&perp;/g, '⊥');
    str = str.replace(/&sdot;/g, '⋅');
    return str;
}

// HTML 支持的希腊字母
function strGreeceDiscode(str) {
    str = str.replace(/&Alpha;/g, 'Α');
    str = str.replace(/&Beta;/g, 'Β');
    str = str.replace(/&Gamma;/g, 'Γ');
    str = str.replace(/&Delta;/g, 'Δ');
    str = str.replace(/&Epsilon;/g, 'Ε');
    str = str.replace(/&Zeta;/g, 'Ζ');
    str = str.replace(/&Eta;/g, 'Η');
    str = str.replace(/&Theta;/g, 'Θ');
    str = str.replace(/&Iota;/g, 'Ι');
    str = str.replace(/&Kappa;/g, 'Κ');
    str = str.replace(/&Lambda;/g, 'Λ');
    str = str.replace(/&Mu;/g, 'Μ');
    str = str.replace(/&Nu;/g, 'Ν');
    str = str.replace(/&Xi;/g, 'Ν');
    str = str.replace(/&Omicron;/g, 'Ο');
    str = str.replace(/&Pi;/g, 'Π');
    str = str.replace(/&Rho;/g, 'Ρ');
    str = str.replace(/&Sigma;/g, 'Σ');
    str = str.replace(/&Tau;/g, 'Τ');
    str = str.replace(/&Upsilon;/g, 'Υ');
    str = str.replace(/&Phi;/g, 'Φ');
    str = str.replace(/&Chi;/g, 'Χ');
    str = str.replace(/&Psi;/g, 'Ψ');
    str = str.replace(/&Omega;/g, 'Ω');
    str = str.replace(/&alpha;/g, 'α');
    str = str.replace(/&beta;/g, 'β');
    str = str.replace(/&gamma;/g, 'γ');
    str = str.replace(/&delta;/g, 'δ');
    str = str.replace(/&epsilon;/g, 'ε');
    str = str.replace(/&zeta;/g, 'ζ');
    str = str.replace(/&eta;/g, 'η');
    str = str.replace(/&theta;/g, 'θ');
    str = str.replace(/&iota;/g, 'ι');
    str = str.replace(/&kappa;/g, 'κ');
    str = str.replace(/&lambda;/g, 'λ');
    str = str.replace(/&mu;/g, 'μ');
    str = str.replace(/&nu;/g, 'ν');
    str = str.replace(/&xi;/g, 'ξ');
    str = str.replace(/&omicron;/g, 'ο');
    str = str.replace(/&pi;/g, 'π');
    str = str.replace(/&rho;/g, 'ρ');
    str = str.replace(/&sigmaf;/g, 'ς');
    str = str.replace(/&sigma;/g, 'σ');
    str = str.replace(/&tau;/g, 'τ');
    str = str.replace(/&upsilon;/g, 'υ');
    str = str.replace(/&phi;/g, 'φ');
    str = str.replace(/&chi;/g, 'χ');
    str = str.replace(/&psi;/g, 'ψ');
    str = str.replace(/&omega;/g, 'ω');
    str = str.replace(/&thetasym;/g, 'ϑ');
    str = str.replace(/&upsih;/g, 'ϒ');
    str = str.replace(/&piv;/g, 'ϖ');
    str = str.replace(/&middot;/g, '·');
    return str;
}

function strcharacterDiscode(str) {
    // 加入常用解析
    str = str.replace(/&nbsp;/g, ' ');
    str = str.replace(/&ensp;/g, ' ');
    str = str.replace(/&emsp;/g, '　');
    str = str.replace(/&quot;/g, "'");
    str = str.replace(/&amp;/g, '&');
    str = str.replace(/&lt;/g, '<');
    str = str.replace(/&gt;/g, '>');
    str = str.replace(/&#8226;/g, '•');
    return str;
}
// HTML 支持的其他实体
function strOtherDiscode(str) {
    str = str.replace(/&OElig;/g, 'Œ');
    str = str.replace(/&oelig;/g, 'œ');
    str = str.replace(/&Scaron;/g, 'Š');
    str = str.replace(/&scaron;/g, 'š');
    str = str.replace(/&Yuml;/g, 'Ÿ');
    str = str.replace(/&fnof;/g, 'ƒ');
    str = str.replace(/&circ;/g, 'ˆ');
    str = str.replace(/&tilde;/g, '˜');
    str = str.replace(/&ensp;/g, '');
    str = str.replace(/&emsp;/g, '');
    str = str.replace(/&thinsp;/g, '');
    str = str.replace(/&zwnj;/g, '');
    str = str.replace(/&zwj;/g, '');
    str = str.replace(/&lrm;/g, '');
    str = str.replace(/&rlm;/g, '');
    str = str.replace(/&ndash;/g, '–');
    str = str.replace(/&mdash;/g, '—');
    str = str.replace(/&lsquo;/g, '‘');
    str = str.replace(/&rsquo;/g, '’');
    str = str.replace(/&sbquo;/g, '‚');
    str = str.replace(/&ldquo;/g, '“');
    str = str.replace(/&rdquo;/g, '”');
    str = str.replace(/&bdquo;/g, '„');
    str = str.replace(/&dagger;/g, '†');
    str = str.replace(/&Dagger;/g, '‡');
    str = str.replace(/&bull;/g, '•');
    str = str.replace(/&hellip;/g, '…');
    str = str.replace(/&permil;/g, '‰');
    str = str.replace(/&prime;/g, '′');
    str = str.replace(/&Prime;/g, '″');
    str = str.replace(/&lsaquo;/g, '‹');
    str = str.replace(/&rsaquo;/g, '›');
    str = str.replace(/&oline;/g, '‾');
    str = str.replace(/&euro;/g, '€');
    str = str.replace(/&trade;/g, '™');
    str = str.replace(/&larr;/g, '←');
    str = str.replace(/&uarr;/g, '↑');
    str = str.replace(/&rarr;/g, '→');
    str = str.replace(/&darr;/g, '↓');
    str = str.replace(/&harr;/g, '↔');
    str = str.replace(/&crarr;/g, '↵');
    str = str.replace(/&lceil;/g, '⌈');
    str = str.replace(/&rceil;/g, '⌉');
    str = str.replace(/&lfloor;/g, '⌊');
    str = str.replace(/&rfloor;/g, '⌋');
    str = str.replace(/&loz;/g, '◊');
    str = str.replace(/&spades;/g, '♠');
    str = str.replace(/&clubs;/g, '♣');
    str = str.replace(/&hearts;/g, '♥');
    str = str.replace(/&diams;/g, '♦');
    str = str.replace(/&#39;/g, "'");
    return str;
}

export function strDiscode(str) {
    str = strNumDiscode(str);
    str = strGreeceDiscode(str);
    str = strcharacterDiscode(str);
    str = strOtherDiscode(str);
    return str;
}
export function formatRichText(html) {
    let newContent = html.replace(/<img[^>]*>/gi, (match, capture) => {
        match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '');
        match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '');
        match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '');
        return match;
    });
    newContent = newContent.replace(/style="[^"]+"/gi, (match, capture) => {
        match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi, 'max-width:100%;');
        return match;
    });
    newContent = newContent.replace(/<br[^>]*\/>/gi, '');
    newContent = strDiscode(newContent);
    newContent = newContent.replace(/<img/gi, '<img style="max-width:100%;height:auto;display:block;margin-top:0;margin-bottom:0;"');
    return newContent;
}

export async function getStorage(key) {
    const {
        data: result,
    } = await api.getStorage({
        key,
    }).catch((err) => {
        // console.log(err);
        return {
            data: null,
        };
    });
    return result;
}

export async function setStorage(key, value) {
    await api.setStorage({
        key,
        data: value,
    });
}

export function getOrderStatus1(order: Order.ListItem) {
    const status = order.status;
    const delivery = order.delivery;
    const isComplete = order.is_finish;

    switch (status) {
    case 'init':
        return '待支付';
    case 'paid':
        if (order.is_prepay && !order.final_payment) {
            return '余款未结';
        } else if (isComplete) {
            return '已签收';
        } else if (delivery) {
            if (delivery === 2) {
                return '已发货';
            } else if (delivery === 1) {
                return '待发货';
            }
            return '';
        } else {
            return '';
        }
    case 'close':
        return '已关闭';
    case 'refund':
        return '已退款';
    }
}

export function getOrderStatus(status: Order.Status, delivery, isComplete) {
    switch (status) {
    case 'init':
        return '待支付';
    case 'paid':
        if (isComplete) {
            return '已签收';
        } else if (delivery) {
            if (delivery === 2) {
                return '已发货';
            } else if (delivery === 1) {
                return '待发货';
            }
            return '';
        } else {
            return '';
        }
    case 'close':
        return '已关闭';
    case 'refund':
        return '已退款';
    }
}

export function getManageOrderStatus(status: Order.Status, type, isFinish: boolean, final, delivery, buyerConfirm) {
    switch (status) {
        case 'init':
        case 'pay_pending':
            return '待支付';
        case 'paid':
            if (final === 0) {
                return '余款未结';
            } else {
                if (delivery === 0) {
                    if (isFinish) {
                        return '确认收货';
                    } else {
                        return '未交货';
                    }
                } else if (delivery === 1) {
                    return '等待发货';
                } else if (delivery === 2) {
                    if (isFinish && buyerConfirm) {
                        return '已收货';
                    } else {
                        return '已发货';
                    }
                }
            }
            return '';
        case 'close':
            return '已关闭';
        case 'refund':
        case 'refund_pending':
            return '已退款';
        }
}

export function repeat(str, times) {
    let result = '';
    for (let i = 0; i < times; i++) {
        result += '*';
    }
    return result;
}

export function isTabbarPage(page) {
    return TABBAR_PAGES.indexOf(page) >= 0;
}

/**
 * 当max的参数数量到达一定程度时好像会出错
 */
 export function mathMax(list) {
    if (!list || list.length === 0) {
        return;
    }
    let max = list[0];
    for (let i = 1, len = list.length; i < len; i++) {
        if (list[i] > max) {
            max = list[i];
        }
    }

    return max;
}

/**
 * 当max的参数数量到达一定程度时好像会出错
 */
export function mathMin(list) {
    if (!list || list.length === 0) {
        return;
    }
    let min = list[0];
    for (let i = 1, len = list.length; i < len; i++) {
        if (list[i] < min) {
            min = list[i];
        }
    }

    return min;
}

/**
 * 获取价格字符串
 * @param price
 *  - min
 *  - max
 * @return string
 */
export function formatPrice(price) {
    if (price.min === price.max) {
        return currency(price.min);
    } else {
        return `${currency(price.min)}-${currency(price.max)}`;
    }
}

export function setLike(list) {
    const result = [];
    const map = {};
    for (let i = 0, len = list.length; i < len; i++) {
        const item = list[i];
        if (!map[item]) {
            result.push(item);
            map[item] = 1;
        }
    }
    return result;
}

export const is = {
    iPhoneXSeries(model) {
        return model && model.indexOf('iPhone X') >= 0;
    },
};

export function getVideoPoster(videoSrc) {
    return `${videoSrc}?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast,ar_auto`;
}

export function debounce(fn, time = 100) {
    let timer = null;
    return function(...args) {
        const ctx = this;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            timer = null;
            fn.call(ctx, args);
        }, time);
    };
}

export function getOrderKey(objParams) {
    const tempKeyArr = ['start', 'end', 'userId', 'shopId', 'level', 'referrerId', 'name'];
    const values = Object.values(objParams);
    const keys = Object.keys(objParams);
    return tempKeyArr.map((item) => {
        const index = keys.indexOf(item);
        return index === -1 ? 'undefined' : (values[index] || 'undefined');
    }).join('_');
}
export function getRebateKey(objParams) {
    const tempKeyArr = ['start', 'end', 'shopId', 'identity', 'referrerId', 'referrerLevel'];
    const values = Object.values(objParams);
    const keys = Object.keys(objParams);
    return tempKeyArr.map((item) => {
        const index = keys.indexOf(item);
        return index === -1 ? 'undefined' : (values[index] || 'undefined');
    }).join('_');
}
export function getUserDataKey(objParams) {
    const tempKeyArr = ['start', 'end', 'userId', 'shopId', 'level', 'search'];
    const values = Object.values(objParams);
    const keys = Object.keys(objParams);
    return tempKeyArr.map((item) => {
        const index = keys.indexOf(item);
        return index === -1 ? 'undefined' : (values[index] || 'undefined');
    }).join('_');
}
export function getRankKey(objParams) {
    const tempKeyArr = ['level', 'interval', 'type'];
    const values = Object.values(objParams);
    const keys = Object.keys(objParams);
    return tempKeyArr.map((item) => {
        const index = keys.indexOf(item);
        return index === -1 ? 'undefined' : (values[index] || 'undefined');
    }).join('_');
}

export function getFirstDayOfMonth(date) {
    date.setDate(1);
    return dateFormat(date);
}

export function getFirstDayOfSeason(date) {
    const month = date.getMonth();
    if (month < 3) {
        date.setMonth(0);
    } else if (month < 6) {
        date.setMonth(3);
    } else if (month < 9) {
        date.setMonth(6);
    } else {
        date.setMonth(9);
    }
    date.setDate(1);
    return dateFormat(date);
}

export function getFirstDayOfYear(date) {
    date.setMonth(0);
    date.setDate(1);
    return dateFormat(date);
}

export function objScene(scene: string) {
    const decodeScene = decodeURIComponent(scene);
    const sceneArr = decodeScene.split('#');
    return {
        referrer: sceneArr[0],
        id: sceneArr[1],
        type: sceneArr[2],
    };
}

export const TRUE = () => true;

const handlerMap: { [key: string]: number | null } = {};

/**
 * 合并调用并延迟，目前只能用于watch
 * @param delay 延迟毫秒
 */
export function WatchDelay(str: string, delay: number) {
    return createDecorator((options, key) => {
        const handlerId = [ options.name, str ].join('_');
        // @ts-ignore
        const originalMethodName = options.watch[str][0].handler;
        // @ts-ignore
        const originalMethod = options.methods[originalMethodName];

        // @ts-ignore
        options.watch[str] = function wrapperMethod(...args) {
            const handler = handlerMap[handlerId];

            if (handler) {
                window.clearTimeout(handler);
                handlerMap[handlerId] = null;
            }
            handlerMap[handlerId] = window.setTimeout(async () => {
                // @ts-ignore
                originalMethod.apply(this, args);
                handlerMap[handlerId] = null;
            }, delay);
        };
    });
}

/** 按照key的字母序排列value */
export function getMapKey(obj: object) {
    const keys = Object.keys(obj);
    // @ts-ignore
    return keys.sort().map((key) => obj[key]).join('_');
}

let lastCheckTime: number | null = null;

/**
 * 尝试检查版本更新
 */
export function tryCheckVersionUpdate() {
    // 每小时检查一次
    if (lastCheckTime && Date.now() < lastCheckTime + 60 * 60 * 1000) {
        return;
    }

    // 执行更新逻辑
    if (wx.getUpdateManager) {
        const updateManager = wx.getUpdateManager();
        updateManager.onCheckForUpdate((res) => {
            // 请求完新版本信息的回调
            // console.log('是否有新版本：', res.hasUpdate);
        });
        updateManager.onUpdateReady(() => {
            wx.showModal({
                title: '更新提示',
                content: '新版本已经准备好，是否重启应用？',
                showCancel: false,
                success(res) {
                    if (res.confirm) {
                        // 新的版本已经下载好，调用 applyUpdate 应用新版本并重启
                        updateManager.applyUpdate();
                    }
                },
            });
        });
        lastCheckTime = Date.now();
    }
}
